package db

import (
	"context"
	"fmt"
	"github.com/zeromicro/go-zero/core/logx"
	clientv3 "go.etcd.io/etcd/client/v3"
	"payme3000/framework/errorx"
	"strings"
	"sync"
	"time"
)

var (
	etcdLock sync.RWMutex
	etcdMap  = map[Type]*clientv3.Client{}
)

func GetEtcd(dbType Type) *clientv3.Client {
	etcdLock.RLock()
	defer etcdLock.RUnlock()

	if db, ok := etcdMap[dbType]; ok {
		return db
	}

	return nil
}

func CreateEtcd(dbType Type, config *Config) error {
	etcdLock.Lock()
	defer etcdLock.Unlock()

	// 锁定后再检查一次
	if client := etcdMap[dbType]; client != nil {
		return nil
	}

	endpoints := strings.Split(config.Host, ",")
	if len(endpoints) == 0 {
		return errorx.Throw(context.Background(), fmt.Sprintf("illegal etcd host with config:%+v", config))
	}

	conf := clientv3.Config{
		Endpoints:   endpoints,
		DialTimeout: 5 * time.Second,
	}

	if config.Username != "" {
		conf.Username = config.Username
	}

	if config.Password != "" {
		conf.Password = config.Password
	}

	cli, err := clientv3.New(conf)
	if err != nil {
		return errorx.Throw(context.Background(), err)
	}

	etcdMap[dbType] = cli

	logx.Infof("create etcd done with dbType:%d, host:%s, db:%s", dbType, config.Host, config.Db)

	return nil
}

func StopEtcd() {
	etcdLock.RLock()
	defer etcdLock.RUnlock()

	for _, etcd := range etcdMap {
		errorx.Catch(context.Background(), etcd.Close())
	}
}
